/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.cje.constant.exception;

// import com.fasterxml.jackson.annotation.JsonFormat;

import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.chframework.boot.core.support.ApiHelper;
import com.chframework.common.exception.UtilityException;
import com.chframework.common.web.IApiStatus;

import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * api 返回对象状态的定义
 */
// @JsonFormat(shape = JsonFormat.Shape.OBJECT) // 序列化枚举类型，所有字段都会出现在JSON字符串中，JSON字符串表示的是一个JSON对象
public enum ErrorStatusEnum implements IApiStatus {
    UNABLE_GET_DISTRIBUTED_LOCKS("D0601", "获取分布式锁失败"),
    UNABLE_GET_CURRENT_SESSION_USER("D0602", "获取本地会话的认证用户失败，无法明确SESSION属性值的返回类型"),
    UNABLE_GET_CURRENT_SESSION_DATA("D0603", "获取本地会话的认证用户失败，无法获取指定的SESSION属性值"),
    UNSUPPORT_HTTP_METHOD("D0604", "不支持该网络服务的请求方式"),
    INCORRECT_APP_SECRET_KEY("D0605", "开放平台密钥校验失败"),
    INVALID_APP_KEY("D0606", "开放平台公钥不存在");

    ErrorStatusEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }

    private String code;
    private String message;

    @JsonValue // 这个注解标注在某个getter方法上，表示该方法是当前枚举的实际表示，只有当前字段的常量值会出现在JSON字符串中
    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getMessage() {
        return this.message;
    }

    @Override
    public String toJSON() throws UtilityException {
        return ApiHelper.toJSON(this);
    }

    /**
     * Jackson反序列化
     */
    @JsonCreator
    public static ErrorStatusEnum fromCode(String code) {
        if (keyValuePairs.size() <= 0) {
            TreeMap<String, String> treeMap = Stream.of(ErrorStatusEnum.values())
                    .collect(Collectors.toMap(
                            ErrorStatusEnum::getCode,
                            ErrorStatusEnum::name,
                            (oldValue, newValue) -> newValue,
                            TreeMap::new));
            keyValuePairs.putAll(treeMap);
        }
        if (!keyValuePairs.containsKey(code)) {
            throw new IllegalArgumentException(String.valueOf(code));
        }
        return ErrorStatusEnum.valueOf(keyValuePairs.get(code));
    }

    /**
     * 唯一标识字段 与 enum-name的映射关系
     */
    private static TreeMap<String, String> keyValuePairs = new TreeMap<>();

    /**
     * hutool反序列化
     * 根据特定字段获取 具体的 枚举实例，其实，code也可以是不同枚举字段的组合，也可以是一个对象，只要求它们的组合是唯一的，能够映射唯一的一个枚举实例即可。
     */
    public static ErrorStatusEnum get(JSONObject jsonObj) throws IllegalArgumentException {
        String code = String.valueOf(jsonObj.get(ApiHelper.OBJECT_IDENTITY_KEY));
        return fromCode(code);
    }
}
